package top.haijunit.work.core.filter;

import cn.hutool.core.text.CharSequenceUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import top.haijunit.work.core.doamin.Constant;
import top.haijunit.work.core.doamin.ExceptionEnum;
import top.haijunit.work.core.doamin.ExceptionServer;
import top.haijunit.work.core.doamin.Result;
import top.haijunit.work.core.redis.RedissonUtils;
import top.haijunit.work.utils.SpringWebUtils;

import java.io.IOException;

/**
 * 验证码过滤器
 *
 * @author zhanghaijun
 * @since 2024-09-19
 */
@Slf4j
@WebFilter(urlPatterns = "/login")
public class LoginCaptchaFilter extends OncePerRequestFilter {

    private static final String CAPTCHA_KEY = "captcha:key";
    private static final String CAPTCHA_VALUE = "captcha";
    private static final String REDIS_CAPTCHA = "captcha:%s";

    @Override
    protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException {
        String url = request.getRequestURI();
        if ("/login".equals(url) && request.getMethod().equals("POST")) {
            try {
                validate(request);
            } catch (Exception e) {
                SpringWebUtils.writeJson(response, Result.of(ExceptionEnum.PARAMS_CAPTCHA_ERROR, e.getMessage()));
            }
        }
        filterChain.doFilter(request, response);
    }

    // 校验验证码逻辑
    private void validate(HttpServletRequest request) {
        String code = request.getParameter(Constant.CAPTCHA_KEY);
        if (StringUtils.isBlank(code)) {
            code = request.getHeader(Constant.CAPTCHA_KEY);
        }
        if (StringUtils.isBlank(code)) {
            throw new ExceptionServer("验证码错误");
        }
        String value = request.getParameter(Constant.CAPTCHA_VALUE);
        if (StringUtils.isBlank(value)) {
            value = request.getHeader(Constant.CAPTCHA_VALUE);
        }
        if (StringUtils.isBlank(value)) {
            throw new ExceptionServer("验证码参数错误");
        }
        if (!CharSequenceUtil.equalsIgnoreCase(value, RedissonUtils.getCacheObject(String.format(Constant.REDIS_CAPTCHA, code)))) {
            throw new ExceptionServer("验证码错误");
        }
    }
}
